#include <iostream>

class Array
{
	static const int DEFAULT_SIZE = 1;
	static const int MULTIPLIER = 2;
public:
	explicit Array(size_t size)
	: _size(size)
	, _capacity(size)
	, _m(new int[size])
	{
	}

	Array()
	: _size(DEFAULT_SIZE)
	, _capacity(DEFAULT_SIZE)
	, _m(new int[DEFAULT_SIZE])
	{
	}

	int get(size_t index) const
	{
		if (index < 0 || index >= _size)
			return 0; // throw?
		return _m[index];
	}

	void set(size_t index, int value)
	{
		if (index < 0 || index >= _size)
			return; // throw?

		_m[index] = value;
	}

	void push_back(int newEl)
	{
		if (_capacity == _size)
		{
			Array t(_capacity * MULTIPLIER);
			std::swap(t._capacity, this->_capacity);
			std::swap(t._m, this->_m);
			std::copy(t._m, t._m + t._size, _m);
		}

		set(_size++, newEl);
	}

	~Array()
	{
		delete[] _m;
	}

	Array(const Array& arr)
	: _size(arr._size)
	, _capacity(arr._capacity)
	, _m(new int[_capacity])
	{
		std::copy(arr._m, arr._m + arr._size, _m);
	}

	Array& operator=(const Array& arr)
	{
		if (this == &arr)
			return *this;

		Array t(arr);

		swap(t);

		return *this;
	}

	void swap(Array& arr)
	{
		std::swap(arr._size, this->_size);
		std::swap(arr._capacity, this->_capacity);
		std::swap(arr._m, this->_m);
	}

	size_t size() const
	{
		return _size;
	}

	size_t capacity() const
	{
		return _capacity;
	}

private:
	size_t _size;
	size_t _capacity;
	int* _m;	
};

int main(int argc, char const *argv[])
{
	const int N = 10;
	Array a(N);


	for (int i = 0; i < N; ++i)
	{
		a.set(i, i);
	}

	Array b(a);

	Array c(N);

	c = b;

	for (int i = c.size(); i < 2*N; ++i)
	{
		c.push_back(i);
	}

	//c = b;

	std::cout << "c.capacity = " << c.capacity() << std::endl;

	c.push_back(20);

	for (int i = 0; i < c.size(); ++i)
	{
		std::cout << c.get(i) << std::endl;
	}	

	std::cout << "c.capacity = " << c.capacity() << std::endl;
	return 0;
}